From 1d274df151b3b7d28ead42792ced85ae8e94b328 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 3 Feb 2009 18:14:19 +0000 Subject: [PATCH] x86: avoid redundant TLB flushes While in some places the guest requested flushes were already folded into the deferred ops, this wasn't done consistently. Also avoid using an uninitialized variable, even if doing so has no correctness issue. Signed-off-by: Jan Beulich --- xen/arch/x86/mm.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 55caac0aeb..6fe26a3468 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2773,7 +2773,7 @@ int do_mmuext_op( } case MMUEXT_TLB_FLUSH_ALL: - flush_tlb_mask(d->domain_dirty_cpumask); + this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_ALL_TLBS; break; case MMUEXT_INVLPG_ALL: @@ -3567,34 +3567,40 @@ int do_update_va_mapping(unsigned long va, u64 val64, if ( pl1e ) guest_unmap_l1e(v, pl1e); - process_deferred_ops(); - switch ( flags & UVMF_FLUSHTYPE_MASK ) { case UVMF_TLB_FLUSH: switch ( (bmap_ptr = flags & ~UVMF_FLUSHTYPE_MASK) ) { case UVMF_LOCAL: - flush_tlb_local(); + this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_TLB; break; case UVMF_ALL: - flush_tlb_mask(d->domain_dirty_cpumask); + this_cpu(percpu_mm_info).deferred_ops |= DOP_FLUSH_ALL_TLBS; break; default: + if ( this_cpu(percpu_mm_info).deferred_ops & DOP_FLUSH_ALL_TLBS ) + break; if ( unlikely(!is_pv_32on64_domain(d) ? get_user(vmask, (unsigned long *)bmap_ptr) : get_user(vmask, (unsigned int *)bmap_ptr)) ) - rc = -EFAULT; + rc = -EFAULT, vmask = 0; pmask = vcpumask_to_pcpumask(d, vmask); + if ( cpu_isset(smp_processor_id(), pmask) ) + this_cpu(percpu_mm_info).deferred_ops &= ~DOP_FLUSH_TLB; flush_tlb_mask(pmask); break; } break; case UVMF_INVLPG: + if ( this_cpu(percpu_mm_info).deferred_ops & DOP_FLUSH_ALL_TLBS ) + break; switch ( (bmap_ptr = flags & ~UVMF_FLUSHTYPE_MASK) ) { case UVMF_LOCAL: + if ( this_cpu(percpu_mm_info).deferred_ops & DOP_FLUSH_TLB ) + break; if ( !paging_mode_enabled(d) || (paging_invlpg(v, va) != 0) ) flush_tlb_one_local(va); @@ -3606,14 +3612,18 @@ int do_update_va_mapping(unsigned long va, u64 val64, if ( unlikely(!is_pv_32on64_domain(d) ? get_user(vmask, (unsigned long *)bmap_ptr) : get_user(vmask, (unsigned int *)bmap_ptr)) ) - rc = -EFAULT; + rc = -EFAULT, vmask = 0; pmask = vcpumask_to_pcpumask(d, vmask); + if ( this_cpu(percpu_mm_info).deferred_ops & DOP_FLUSH_TLB ) + cpu_clear(smp_processor_id(), pmask); flush_tlb_one_mask(pmask, va); break; } break; } + process_deferred_ops(); + return rc; } -- 2.30.2